module Q.IR.Common where

import Data.List (foldl')
import Text.Printf (printf)

--------------------------------------------------------------------------------
-- Layouts

data Layout
  = LInt
  | LPair Layout Layout

--------------------------------------------------------------------------------
-- Values

data Value
  = VInt Int
  | VCons !Value !Value

instance Show Value where
  showsPrec _ (VInt i)      = shows i
  showsPrec _ (VCons v1 v2) = showString "(" . shows v1 .
                              showString "," . shows v2 . showString ")"

valueToPair :: Value -> (Value, Value)
valueToPair (VCons v1 v2) = (v1, v2)
valueToPair _             = error "value is not a pair"

valueToInt :: Value -> Int
valueToInt (VInt n) = n
valueToInt _        = error "value is not an integer"

--------------------------------------------------------------------------------
-- Paths

data Proj = P0 | P1 deriving (Eq, Show)
type Path = [Proj]

proj :: Proj -> (a, a) -> a
proj P0 = fst
proj P1 = snd

follow :: Value -> Path -> Value
follow = foldl' (flip proj . valueToPair)

--------------------------------------------------------------------------------
-- Identifiers

newtype Id = Id { name :: String } deriving (Eq, Ord)

instance Show Id where
  show = printf "`%s'" . name
